package net.chasing.androidbaseconfig.util;

import android.Manifest;
import android.app.Activity;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Color;
import android.net.Uri;
import android.provider.CalendarContract;

import androidx.fragment.app.FragmentActivity;

import net.chasing.androidbaseconfig.util.permission.PermissionUtils;

import java.util.Calendar;
import java.util.TimeZone;

/**
 * 系统日历辅助类
 */
public class CalendarUtils {

    private CalendarUtils() {
    }

    private static final String CALENDARS_ACCOUNT_NAME = "calendar@superrabbit.com";
    private static final String CALENDARS_ACCOUNT_TYPE = "LOCAL";
    private static final String CALENDARS_DISPLAY_NAME = "超级兔子便签";

    // 检查日历是否有账户
    private static int checkCalendarAccount(Context context) {
        try (Cursor userCursor = context.getContentResolver().query(CalendarContract.Calendars.CONTENT_URI,
                null, null, null, null)) {
            if (userCursor == null)//查询返回空值
                return -1;
            int count = userCursor.getCount();
            if (count > 0) {//存在现有账户，判断账户名称是否是应用对应显示的名称
                while (userCursor.moveToNext()) {
                    int nameIndex = userCursor.getColumnIndex(CalendarContract.Calendars.ACCOUNT_NAME);
                    String accountName = userCursor.getString(nameIndex);
                    if (CALENDARS_ACCOUNT_NAME.equals(accountName)) {
                        int columnIndex = userCursor.getColumnIndex(CalendarContract.Calendars._ID);
                        return userCursor.getInt(columnIndex);
                    }
                }
            }
            return -1;
        }
    }

    // 添加账户
    private static long addCalendarAccount(Context context) {
        TimeZone timeZone = TimeZone.getDefault();
        ContentValues value = new ContentValues();
        // 路径来源显示名称：
        value.put(CalendarContract.Calendars.NAME, CALENDARS_DISPLAY_NAME);

        value.put(CalendarContract.Calendars.ACCOUNT_NAME, CALENDARS_ACCOUNT_NAME);
        value.put(CalendarContract.Calendars.ACCOUNT_TYPE, CALENDARS_ACCOUNT_TYPE);
        value.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, CALENDARS_DISPLAY_NAME);
        value.put(CalendarContract.Calendars.VISIBLE, 1);
        value.put(CalendarContract.Calendars.CALENDAR_COLOR, Color.BLUE);
        value.put(CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL, CalendarContract.Calendars.CAL_ACCESS_OWNER);
        value.put(CalendarContract.Calendars.SYNC_EVENTS, 1);
        value.put(CalendarContract.Calendars.CALENDAR_TIME_ZONE, timeZone.getID());
        value.put(CalendarContract.Calendars.OWNER_ACCOUNT, CALENDARS_ACCOUNT_NAME);
        value.put(CalendarContract.Calendars.CAN_ORGANIZER_RESPOND, 0);

        Uri calendarUri = CalendarContract.Calendars.CONTENT_URI.buildUpon()
                .appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
                .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, CALENDARS_ACCOUNT_NAME)
                .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE, CALENDARS_ACCOUNT_TYPE)
                .build();

        Uri result = context.getContentResolver().insert(calendarUri, value);
        return result == null ? -1 : ContentUris.parseId(result);
    }

    // 检查是否已经添加了日历账户，如果没有添加先添加一个日历账户再查询
    private static int checkAndAddCalendarAccount(Context context) {
        int oldId = checkCalendarAccount(context);
        if (oldId >= 0) {
            return oldId;
        } else {
            long addId = addCalendarAccount(context);
            if (addId >= 0) {
                return checkCalendarAccount(context);
            } else {
                return -1;
            }
        }
    }

    public static void requestPermission(FragmentActivity activity) {
        PermissionUtils.requestPermission(activity, isAllGranted -> {},
                Manifest.permission.WRITE_CALENDAR, Manifest.permission.READ_CALENDAR);
    }

    public static void deleteCalendarAccount(FragmentActivity activity) {
        if (PermissionUtils.requestPermission(activity, isAllGranted -> {},
                Manifest.permission.WRITE_CALENDAR, Manifest.permission.READ_CALENDAR)) {
            return;
        }
        int oldId = checkCalendarAccount(activity);
        if (oldId >= 0) { // 存在账号，则进行删除
            activity.getContentResolver().delete(CalendarContract.Calendars.CONTENT_URI,
                    CalendarContract.Calendars._ID + "=?", new String[]{String.valueOf(oldId)});
        }
    }

    // 添加日程 设置日程标题 添加日程描述 日程开始时间（毫秒）

    /**
     * 向日历插入提醒事件
     *
     * @param title       日程标题
     * @param description 日程描述
     * @param beginTime   日程开始时间（毫秒）
     * @param endTime     日程结束时间（毫秒）
     * @param remind      提前多久提醒（分钟）
     * @return 返回插入事件id和提醒事件id，long[0]为插入事件id  long[1]为插入提醒事件id
     * 插入事件id：-1代表插入失败  0 请求权限中
     */
    public static long[] addCalendarEvent(String title, String description,
                                          long beginTime, long endTime, int remind) {
        long[] ids = new long[]{-1, -1};
        try {
            Activity activity = ActivityUtils.getActivityUtils().currentActivity();
            if (activity != null) {
                if (!PermissionUtils.checkPermissions(activity, Manifest.permission.WRITE_CALENDAR, Manifest.permission.READ_CALENDAR)) {
                    return ids;
                }
                // 获取日历账户的id
                int calId = checkAndAddCalendarAccount(activity);
                if (calId < 0) {
                    // 获取账户id失败直接返回，添加日历事件失败
                    return ids;
                }

                ContentValues event = new ContentValues();
                event.put(CalendarContract.Events.TITLE, title);
                event.put(CalendarContract.Events.DESCRIPTION, description);
                // 插入账户的id
                event.put(CalendarContract.Events.CALENDAR_ID, calId);

                Calendar calendar = Calendar.getInstance();
                calendar.setTimeInMillis(beginTime);//设置日程开始时间
                long start = calendar.getTime().getTime();
                // 经测试，华为的：开始时间等于结束时间，则不会弹出通知，所以这里添加统一处理，时间相等，则结束时间延后一分钟
                if (endTime == beginTime)
                    endTime += 60000;
                calendar.setTimeInMillis(endTime);//设置日程终止时间
                long end = calendar.getTime().getTime();

                event.put(CalendarContract.Events.DTSTART, start);
                event.put(CalendarContract.Events.DTEND, end);
                event.put(CalendarContract.Events.HAS_ALARM, 1);//设置有闹钟提醒，如果闹钟不响，请检查手机日历闹钟是否设置铃声，是否静音或者音量太小
                event.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());  //这个是时区，必须有，
                //添加事件
                Uri newEvent = activity.getContentResolver().insert(CalendarContract.Events.CONTENT_URI, event);
                if (newEvent == null) { // 添加日历事件失败直接返回
//                    ToastUtils.showShort(activity, "添加事件失败");
                    return ids;
                }

                long eventId = ContentUris.parseId(newEvent);
                ids[0] = eventId;
                //事件提醒的设定
                ContentValues values = new ContentValues();
                values.put(CalendarContract.Reminders.EVENT_ID, eventId);
                values.put(CalendarContract.Reminders.MINUTES, remind);// 提前多久进行提醒
                values.put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALERT);
                Uri insert = activity.getContentResolver().insert(CalendarContract.Reminders.CONTENT_URI, values);
//        context.getContentResolver().insert(Uri.parse("content://com.android.calendar/reminders"), values);
                if (insert == null) {
//                    ToastUtils.showShort(activity, "插入提醒失败");
                } else {
                    long remindId = ContentUris.parseId(insert);
                    ids[1] = remindId;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ids;
    }

    // 删除日程
    public static void deleteCalendarEvent(long eventId, long remindId) {
        try {
            Activity activity = ActivityUtils.getActivityUtils().currentActivity();
            if (activity != null) {
                if (!PermissionUtils.checkPermissions(activity, Manifest.permission.WRITE_CALENDAR,
                        Manifest.permission.READ_CALENDAR))
                    return;

                if (!checkEventExist(activity, eventId)) {
                    return;
                }

                int delete = activity.getContentResolver().delete(CalendarContract.Events.CONTENT_URI,
                        CalendarContract.Events._ID + "=?", new String[]{String.valueOf(eventId)});
                if (delete == -1) {
                    //事件删除失败
//                    ToastUtils.showShort(activity, "删除事件失败");
                } else {
                    if (!checkRemindExist(activity, remindId)) {
                        return;
                    }
                    activity.getContentResolver().delete(CalendarContract.Reminders.CONTENT_URI,
                            CalendarContract.Events._ID + "=?", new String[]{String.valueOf(remindId)});
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 更新日历提醒事件
     *
     * @param title       日程标题
     * @param description 日程描述
     * @param beginTime   日程开始时间（毫秒）
     * @param endTime     日程结束时间（毫秒）
     * @param remind      提前多久提醒（分钟）
     * @return 返回插入事件id和提醒事件id，long[0]为插入事件id  long[1]为插入提醒事件id
     * 插入事件id：-1代表插入失败  0 请求权限中
     */
    public static long updateCalendarEvent(long eventId, long remindId, String title,
                                           String description, long beginTime, long endTime, int remind) {
        try {
            Activity activity = ActivityUtils.getActivityUtils().currentActivity();
            if (activity != null) {
                if (!PermissionUtils.checkPermissions(activity, Manifest.permission.WRITE_CALENDAR,
                        Manifest.permission.READ_CALENDAR)) {
                    return 0;
                }
                ContentValues event = new ContentValues();
                event.put(CalendarContract.Events.TITLE, title);
                event.put(CalendarContract.Events.DESCRIPTION, description);

                Calendar calendar = Calendar.getInstance();
                calendar.setTimeInMillis(beginTime);//设置日程开始时间
                long start = calendar.getTime().getTime();
                // 经测试，华为的：开始时间等于结束时间，则不会弹出通知，所以这里添加统一处理，时间相等，则结束时间延后一分钟
                if (endTime == beginTime)
                    endTime += 60000;
                calendar.setTimeInMillis(endTime);//设置日程终止时间
                long end = calendar.getTime().getTime();

                event.put(CalendarContract.Events.DTSTART, start);
                event.put(CalendarContract.Events.DTEND, end);
                event.put(CalendarContract.Events.HAS_ALARM, 1);//设置有闹钟提醒，如果闹钟不响，请检查手机日历闹钟是否设置铃声，是否静音或者音量太小
                event.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());  //这个是时区，必须有，
                //添加事件
                int update = activity.getContentResolver().update(CalendarContract.Events.CONTENT_URI, event,
                        CalendarContract.Events._ID + "=?", new String[]{String.valueOf(eventId)});
                if (update <= 0) { // 更新日历事件失败直接返回
//                    ToastUtils.showShort(activity, "更新事件失败");
                    return -1;
                }

                //事件提醒的设定
                ContentValues values = new ContentValues();
                values.put(CalendarContract.Reminders.EVENT_ID, eventId);
                values.put(CalendarContract.Reminders.MINUTES, remind);// 提前多久进行提醒
                values.put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALERT);
                int updateRemind = activity.getContentResolver().update(CalendarContract.Reminders.CONTENT_URI, values,
                        CalendarContract.Reminders._ID + "=?", new String[]{String.valueOf(remindId)});
//        context.getContentResolver().insert(Uri.parse("content://com.android.calendar/reminders"), values);
                if (updateRemind <= 0) {
//                    ToastUtils.showShort(activity, "更新提醒失败");
                    return -1;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return eventId;
    }

    private static boolean checkEventExist(Context context, long eventId) {
        try (Cursor userCursor = context.getContentResolver().query(CalendarContract.Events.CONTENT_URI, null,
                CalendarContract.Events._ID + "=?", new String[]{String.valueOf(eventId)}, null)) {
            if (userCursor == null)//查询返回空值
                return false;
            int count = userCursor.getCount();
            return count > 0;
        }
    }

    private static boolean checkRemindExist(Context context, long remindId) {
        try (Cursor userCursor = context.getContentResolver().query(CalendarContract.Reminders.CONTENT_URI, null,
                CalendarContract.Reminders._ID + "=?", new String[]{String.valueOf(remindId)}, null)) {
            if (userCursor == null)//查询返回空值
                return false;
            int count = userCursor.getCount();
            return count > 0;
        }
    }

}
